<?php
/**
 * Auther: Joshua Conero
 * Date: 2017/5/10 0010 15:03
 * Email: brximl@163.com
 * Name: 系统令牌数据模型
 */

namespace app\common\model;
use think\facade\Config;
use think\Model;

class Token extends Model
{
    protected $pk = 'listid';

    /**
     * @return mixed
     */
    public function getListid(){
        return getPkValue('pk_sys_token__listid');
    }
    /**
     * 获取（生成）权限代码
     * @param $data  [type*,uid]  类型必填
     * @return string
     */
    public function access_token($data){
        $code = $data['type'];
        if(isset($data['uid'])){
            $code .= (isset($data['uid'])? $data['uid']:'').rand(100, 999).time();
        }else {
            $code .= rand(100000, 99999) . time();
        }
        $token = sha1($code);
        try {
            $data['listid'] = $this->getListid();
            $data['token'] = $token;
            $this->db()->insert($data);
        }catch (\Exception $e){ // 失败时制空
            $token = '';
        }
        return $token;
    }

    /**
     * 返回或检查-自动登录token
     * @param $uid
     * @param boolean $auto
     * @return mixed|null|string
     */
    public function getAutoLoginToken($uid, $auto=true){
        $token = null;
        $loginConf = Config::get('setting.login');
        $rs = $this->db()
            ->where([
                'uid' => $uid,
                'type'=> $loginConf['code'],
                'invalid_mk'    => 'N'
            ])
            ->find()
            ;
        if($rs){
            $mtime = $rs['mtime'];
            $d1 = new \DateTime($mtime);
            $interval = $d1->diff(new \DateTime('now'));
            $day = $interval->format('%R%a');
            $rs['day'] = intval($day);
            $token = $rs['token'];
            if($rs['day'] > $loginConf['remember_day']){
                // 过期以后是所有有效的代码失效
                $this->save([
                    'invalid_mk' => 'Y'
                ], ['uid' => $uid, 'type'=>$loginConf['code']]);
                $token = null;
            }
        }
        if(empty($token) && $auto){
            $token = $this->access_token([
                'uid' => $uid,
                'type'=> $loginConf['code']
            ]);
        }
        return $token;
    }

    /**
     * 令牌验证是否正确,并且保存访问量
     * @param $token string 令牌
     * @param $type string 类型
     * @return bool
     */
    public function TokenIsValid($token,$type=null){
        $where = ['token'=>$token];
        if($type) $where['type'] = $type;
        $data = $this->db()
            ->where($where)
            ->where('invalid_mk<>\'Y\'')
            ->field('invalid_mk,expire_in,uid,mtime,listid,v_ctt')->find();
        $exist = false;
        if($data){
            $updateCttFn = function () use($data){
                // 更新请求统计次数
                $this->db()->where('listid',$data['listid'])->update(['v_ctt'=>(intval($data['v_ctt'])+1)]);
            };
            if(!empty($data['expire_in'])){
                if(time()-strtotime($data['mtime']) <= $data['expire_in']){
                    $exist = true;
                    call_user_func($updateCttFn);
                }
                else{
                    // 无效以后记录数据库
                    $this->db()->where('listid',$data['listid'])->update(['invalid_mk'=>'Y']);
                }
            }else{
                $exist = true;
                call_user_func($updateCttFn);
            }
        }
        return $exist;
    }
}